﻿#include "chook.h"
#include <QDebug>

namespace ss {

HHOOK g_hookLLKeyboard = NULL;
HHOOK g_hookLLMouse = NULL;
HOOK_CALLBACK_FUNC g_callbackFunc = NULL;

CHook::CHook()
{

}

CHook& CHook::Instance()
{
    static CHook hook;
    return hook;
}

CHook::~CHook()
{
    UnInstallHook();
}

bool CHook::InstallHook(HOOK_CALLBACK_FUNC func)
{
    g_callbackFunc = func;
    InstallLLKeyboardHook();
    InstallLLMouseHook();
    return true;
}

void CHook::UnInstallHook()
{
    if (g_hookLLKeyboard)
    {
        UnhookWindowsHookEx(g_hookLLKeyboard);
        g_hookLLKeyboard = NULL;
    }
    if (g_hookLLMouse)
    {
        UnhookWindowsHookEx(g_hookLLMouse);
        g_hookLLMouse = NULL;
    }
}

bool CHook::InstallLLKeyboardHook()
{
    if (!g_hookLLKeyboard)
    {
        // Global Keyboard Hook
        g_hookLLKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, 0);
    }
    return NULL != g_hookLLKeyboard;
}

bool CHook::InstallLLMouseHook()
{
    qDebug() << __FUNCTION__ << ": threadID=" << GetCurrentThreadId();
    if (!g_hookLLMouse)
    {
        // Global Mouse Hook
        g_hookLLMouse = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, NULL, 0);
    }
    return NULL != g_hookLLMouse;
}

LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (HC_ACTION == code && g_callbackFunc)
    {
        g_callbackFunc();
    }
    return CallNextHookEx(g_hookLLKeyboard, code, wParam, lParam);
}

LRESULT CALLBACK LowLevelMouseProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (HC_ACTION == code && g_callbackFunc)
    {
        g_callbackFunc();
    }
    return CallNextHookEx(g_hookLLMouse, code, wParam, lParam);
}



}
